/** @jsxImportSource @emotion/react */
import { useEffect, useRef, useState } from "react"
import styled from "@emotion/styled"

// 样式组件（保持不变）
const Container = styled.div`
    display: flex;
    flex-direction: column;
    align-items: center;
    min-height: 100vh;
    width: 100vw;
    padding: 15px;
    background: #f5f6fa;
    color: #333;
    font-family: "Segoe UI", sans-serif;
    box-sizing: border-box;
`

const FrequencyDisplay = styled.div`
    font-size: 2.2rem;
    font-weight: bold;
    margin: 0;
`

const VibrationInfo = styled.div`
    font-size: 0.9rem;
    color: #666;
    margin: 2px 0 0 0;
`

const Slider = styled.input`
    width: 80%;
    max-width: 800px;
    margin-bottom: 8px;
`

const Label = styled.div`
    margin: 12px 0 5px 0;
    font-weight: 500;
    width: 80%;
    text-align: left;
    font-size: 0.9rem;
`

const FineTuneBtn = styled.button`
    padding: 6px 12px;
    font-size: 0.85rem;
    background: #6c757d;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.3s;
    margin: 0 4px;

    &:hover {
        background: #5a6268;
    }

    &:disabled {
        opacity: 0.5;
        cursor: not-allowed;
    }
`

const FineTuneContainer = styled.div`
    display: flex;
    justify-content: center;
    margin-bottom: 10px;
    width: 80%;
`

const Canvas = styled.canvas`
    width: 75%;
    height: 200px;
    border: 1px solid #ccc;
    background: white;
    margin-bottom: 10px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    max-width: 1200px;
`

const ControlButton = styled.button<{isPlaying: boolean}>`
    padding: 10px 20px;
    font-size: 0.9rem;
    background: ${props => props.isPlaying ? "#dc3545" : "#007bff"};
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.3s;
    margin: 0 10px;
`

const ControlSection = styled.div`
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 10px;
    width: 75%;
`

const ControlTextContainer = styled.div`
    text-align: center;
    margin: 0 10px;
`

const FrequencySection = styled.div`
    margin-bottom: 10px;
    width: 80%;
    max-width: 1200px;
`

const SectionTitle = styled.h3`
    margin: 12px 0 8px 0;
    color: #495057;
    text-align: left;
    font-size: 1rem;
`

const OctaveRow = styled.div`
    display: flex;
    gap: 8px;
    margin-bottom: 8px;
    flex-wrap: wrap;
    justify-content: center;
`

const FrequencyButton = styled.button<{active: boolean}>`
    padding: 6px 8px;
    font-size: 0.8rem;
    background: ${props => props.active ? "#28a745" : "#e9ecef"};
    color: ${props => props.active ? "white" : "#333"};
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: all 0.2s;
    text-align: center;
    min-width: 90px;
    white-space: pre-line;
`

const BandIndicator = styled.span<{band: string}>`
    font-size: 0.9rem;
    font-weight: 500;
    padding: 3px 8px;
    border-radius: 12px;
    background: ${props => {
        switch(props.band) {
            case '次声波': return '#6c757d33';
            case '低频（可听）': return '#28a74533';
            case '中频（可听）': return '#007bff33';
            case '高频（可听）': return '#dc354533';
            case '超声波': return '#6f42c133';
            default: return '#6c757d33';
        }
    }};
    color: ${props => {
        switch(props.band) {
            case '次声波': return '#6c757d';
            case '低频（可听）': return '#28a745';
            case '中频（可听）': return '#007bff';
            case '高频（可听）': return '#dc3545';
            case '超声波': return '#6f42c1';
            default: return '#6c757d';
        }
    }};
`

export default function FrequencyGenerator() {
    const [frequency, _setFrequency] = useState(440)
    const frequencyRef = useRef(frequency)
    const [volume, setVolume] = useState(0.3)
    const [isPlaying, setIsPlaying] = useState(false)
    const WAVEFORM_DURATION = 0.5;

    // 音频相关引用（新增musicTimerRef管理音乐自动停止）
    const audioCtxRef = useRef<AudioContext | null>(null)
    const oscillatorRef = useRef<OscillatorNode | null>(null)
    const gainRef = useRef<GainNode | null>(null)
    const canvasRef = useRef<HTMLCanvasElement | null>(null)
    const animationRef = useRef<number | null>(null)
    const intervalRef = useRef<number | null>(null)
    const lastTimeRef = useRef<number>(0)
    const phaseRef = useRef<number>(0)
    const musicTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null) // 音乐自动停止定时器

    const useDingSound = frequency < 20;

    const setFrequency = (newFrequency: number) => {
        frequencyRef.current = newFrequency;
        _setFrequency(newFrequency);
    }

    // 原有逻辑函数（保持不变）
    const getFrequencyBand = () => {
        if (frequency < 20) return "次声波";
        if (frequency <= 20000) {
            if (frequency < 500) return "低频（可听）";
            if (frequency <= 2000) return "中频（可听）";
            return "高频（可听）";
        }
        return "超声波";
    }

    const getBandDescription = () => {
        switch(getFrequencyBand()) {
            case '次声波':
                return "人耳不可闻（＜20Hz），如地震波、大象交流声";
            case '低频（可听）':
                return "20-500Hz，如雷声（50-100Hz）、男性说话声（85-180Hz）";
            case '中频（可听）':
                return "500-2000Hz，人耳最敏感，如女性说话声（165-255Hz）、钢琴中音";
            case '高频（可听）':
                return "2000-20000Hz，如鸟鸣（2000-8000Hz）、小提琴高音";
            case '超声波':
                return "人耳不可闻（20000-25000Hz），如蝙蝠回声定位、小型超声设备";
            default:
                return "";
        }
    }

    const baseFrequencies = [
        { value: 1, label: "1 Hz\n地震波 / 超低频（< 20 Hz）" },
        { value: 15, label: "15 Hz\n大象交流（约 14 ~ 24 Hz）" },
        { value: 60, label: "60 Hz\n电源 / 电器频率" },
        { value: 100, label: "100 Hz\n低频音 / 打击乐基音" },
        { value: 150, label: "150 Hz\n男性说话基频（85 ~ 180 Hz）" },
        { value: 200, label: "200 Hz\n女性说话基频（165 ~ 255 Hz）" },
        { value: 300, label: "300 Hz\n儿童说话基频（>300Hz）" },
        { value: 440, label: "440 Hz\n标准 A 音（音乐参考音）" },
        { value: 600, label: "600 Hz\n语音中频 / 共鸣区域" },
        { value: 1000, label: "1000 Hz\n电话铃声 / 中音基准音" },
        { value: 3000, label: "3000 Hz\n高音 / 响亮声音" },
        { value: 5000, label: "5000 Hz\n人声高频 / 昆虫鸣叫" },
        { value: 8000, label: "8000 Hz\n高频音 / 昆虫 / 风声" },
        { value: 20000, label: "20000 Hz\n人类听觉极限（20 kHz，超声起点）" },
        { value: 25000, label: "25000 Hz\n超声清洗 / 超声应用例子（约 25 kHz）" },
    ];

    const musicFrequencies = {
        低音: [
            { note: "1 (Do)", value: 262 },
            { note: "2 (Re)", value: 294 },
            { note: "3 (Mi)", value: 330 },
            { note: "4 (Fa)", value: 349 },
            { note: "5 (So)", value: 392 },
            { note: "6 (La)", value: 440 },
            { note: "7 (Si)", value: 494 }
        ],
        中音: [
            { note: "1 (Do)", value: 523 },
            { note: "2 (Re)", value: 587 },
            { note: "3 (Mi)", value: 659 },
            { note: "4 (Fa)", value: 698 },
            { note: "5 (So)", value: 784 },
            { note: "6 (La)", value: 880 },
            { note: "7 (Si)", value: 988 }
        ],
        高音: [
            { note: "1 (Do)", value: 1046 },
            { note: "2 (Re)", value: 1175 },
            { note: "3 (Mi)", value: 1318 },
            { note: "4 (Fa)", value: 1397 },
            { note: "5 (So)", value: 1568 },
            { note: "6 (La)", value: 1760 },
            { note: "7 (Si)", value: 1976 }
        ]
    };

    const initAudio = () => {
        if (audioCtxRef.current && audioCtxRef.current.state !== "closed") return;

        const audioCtx = new AudioContext()
        const gainNode = audioCtx.createGain()
        gainNode.gain.value = volume

        audioCtxRef.current = audioCtx
        gainRef.current = gainNode
        gainNode.connect(audioCtx.destination)

        setIsPlaying(true)
        startAudioSource()
        drawSimulatedWave()
    }

    const startAudioSource = () => {
        if (!audioCtxRef.current || !gainRef.current) return;

        if (intervalRef.current) {
            clearInterval(intervalRef.current)
            intervalRef.current = null
        }

        if (oscillatorRef.current) {
            oscillatorRef.current.stop()
            oscillatorRef.current.disconnect()
            oscillatorRef.current = null
        }

        if (useDingSound) {
            const interval = 1000 / frequencyRef.current;
            playDingSound()
            intervalRef.current = window.setInterval(() => {
                playDingSound()
            }, interval) as unknown as number;
        } else {
            const oscillator = audioCtxRef.current.createOscillator()
            oscillator.type = "sine"
            oscillator.frequency.value = frequencyRef.current
            oscillator.connect(gainRef.current)
            oscillator.start()
            oscillatorRef.current = oscillator
        }
    }

    const playDingSound = () => {
        if (!audioCtxRef.current || !gainRef.current) return;

        const oscillator = audioCtxRef.current.createOscillator()
        const envelope = audioCtxRef.current.createGain()

        oscillator.type = "sine"
        oscillator.frequency.value = 880

        envelope.gain.setValueAtTime(0, audioCtxRef.current.currentTime)
        envelope.gain.linearRampToValueAtTime(volume, audioCtxRef.current.currentTime + 0.01)
        envelope.gain.exponentialRampToValueAtTime(0.001, audioCtxRef.current.currentTime + 0.3)

        oscillator.connect(envelope)
        envelope.connect(gainRef.current)
        oscillator.start()
        oscillator.stop(audioCtxRef.current.currentTime + 0.3)
    }

    const drawSimulatedWave = () => {
        const canvas = canvasRef.current
        if (!canvas || !isPlaying) return

        const ctx = canvas.getContext("2d")!
        canvas.width = canvas.offsetWidth;
        canvas.height = canvas.offsetHeight;

        const width = canvas.width
        const height = canvas.height
        const centerY = height / 2
        const amplitude = height * 0.4

        let displayFrequency;
        if (frequency <= 500) {
            displayFrequency = frequency * 0.3;
        } else if (frequency <= 2000) {
            displayFrequency = 150 + (frequency - 500) * 0.1;
        } else {
            displayFrequency = 300 + Math.log(frequency / 2000) * 30;
        }
        displayFrequency = Math.min(displayFrequency, 350);

        const secondsPerPixel = WAVEFORM_DURATION / width;

        if (lastTimeRef.current === 0) {
            lastTimeRef.current = performance.now();
        }

        const drawFrame = (timestamp: number) => {
            if (!isPlaying) return;
            animationRef.current = requestAnimationFrame(drawFrame);

            const deltaTime = (timestamp - lastTimeRef.current) / 1000;
            lastTimeRef.current = timestamp;

            phaseRef.current += 2 * Math.PI * frequency * deltaTime;
            phaseRef.current = phaseRef.current % (2 * Math.PI);

            ctx.fillStyle = "white";
            ctx.fillRect(0, 0, width, height);

            ctx.fillStyle = "#333";
            ctx.font = "0.7rem sans-serif";
            ctx.fillText(`0秒`, 5, height - 5);
            ctx.fillText(`${WAVEFORM_DURATION/2}秒`, width/2 - 15, height - 5);
            ctx.fillText(`${WAVEFORM_DURATION}秒`, width - 30, height - 5);
            ctx.beginPath();
            ctx.moveTo(0, height - 10);
            ctx.lineTo(width, height - 10);
            ctx.strokeStyle = "#ccc";
            ctx.lineWidth = 1;
            ctx.stroke();

            const subAudioLineX = width * (20 / 25000);
            ctx.beginPath();
            ctx.setLineDash([5, 5]);
            ctx.moveTo(subAudioLineX, 0);
            ctx.lineTo(subAudioLineX, height - 15);
            ctx.strokeStyle = "#6c757d88";
            ctx.lineWidth = 1;
            ctx.stroke();
            ctx.setLineDash([]);
            ctx.fillStyle = "#6c757d";
            ctx.fillText("20Hz", subAudioLineX + 5, 20);

            const ultraAudioLineX = width * (20000 / 25000);
            ctx.beginPath();
            ctx.setLineDash([5, 5]);
            ctx.moveTo(ultraAudioLineX, 0);
            ctx.lineTo(ultraAudioLineX, height - 15);
            ctx.strokeStyle = "#6f42c188";
            ctx.lineWidth = 1;
            ctx.stroke();
            ctx.setLineDash([]);
            ctx.fillStyle = "#6f42c1";
            ctx.fillText("20000Hz", ultraAudioLineX + 5, 20);

            const lowMidLineX = width * (500 / 25000);
            const midHighLineX = width * (2000 / 25000);
            ctx.beginPath();
            ctx.moveTo(lowMidLineX, 0);
            ctx.lineTo(lowMidLineX, height - 15);
            ctx.strokeStyle = "#28a74522";
            ctx.lineWidth = 1;
            ctx.stroke();
            ctx.beginPath();
            ctx.moveTo(midHighLineX, 0);
            ctx.lineTo(midHighLineX, height - 15);
            ctx.strokeStyle = "#007bff22";
            ctx.lineWidth = 1;
            ctx.stroke();

            ctx.beginPath();
            ctx.moveTo(0, centerY);
            ctx.lineTo(width, centerY);
            ctx.strokeStyle = "#eee";
            ctx.lineWidth = 1;
            ctx.stroke();

            ctx.lineWidth = 2;
            ctx.strokeStyle = frequency < 20 ? "#6c757d" :
                frequency < 500 ? "#28a745" :
                    frequency <= 2000 ? "#007bff" :
                        frequency <= 25000 ? "#6f42c1" :
                            "#6f42c1";

            ctx.beginPath();
            for (let x = 0; x < width; x++) {
                const time = x * secondsPerPixel;
                const y = centerY + Math.sin(phaseRef.current + 2 * Math.PI * frequency * time) * amplitude;
                if (x === 0) {
                    ctx.moveTo(x, y);
                } else {
                    ctx.lineTo(x, y);
                }
            }
            ctx.stroke();
        };

        animationRef.current = requestAnimationFrame(drawFrame);
    }

    // 【修改1】预设按钮点击自动启动（移除isPlaying判断）
    const selectFrequency = (freq: number) => {
        setFrequency(freq);
        // 若音频未初始化，自动启动
        if (!audioCtxRef.current) {
            initAudio();
        } else {
            startAudioSource();
        }
    }

    // 【新增2】音乐频率按钮专属处理（0.5秒自动停止）
    const playMusicNote = (freq: number) => {
        if (musicTimerRef.current) {
            clearTimeout(musicTimerRef.current);
            musicTimerRef.current = null;
        }

        // 1. 设置频率并启动音频
        setFrequency(freq);
        if (!audioCtxRef.current) {
            initAudio();
        } else {
            startAudioSource();
        }
        console.log("播放频率：", freq);
        musicTimerRef.current = setTimeout(() => {
            console.log("自动停止");
            if (oscillatorRef.current) {
                // 👇 加当前时间参数，确保停止生效
                oscillatorRef.current.stop(audioCtxRef.current?.currentTime || 0);
                oscillatorRef.current.disconnect();
                oscillatorRef.current = null;
            }
            if (intervalRef.current) {
                clearInterval(intervalRef.current);
                intervalRef.current = null;
            }
            audioCtxRef.current = null;
            setIsPlaying(false); // 重置播放状态
        }, 1000);
    }

    // 【修改3】频率微调函数（同步支持自动启动）
    const fineTuneFrequency = (step: number) => {
        const newFreq = Math.max(1, Math.min(25000, frequency + step));
        setFrequency(newFreq);
        if (isPlaying || audioCtxRef.current) {
            startAudioSource();
        }
    }

    useEffect(() => {
        if (isPlaying) {
            startAudioSource();
        }
    }, [frequency, isPlaying])

    useEffect(() => {
        if (isPlaying) {
            phaseRef.current = 0;
            lastTimeRef.current = 0;
            drawSimulatedWave();
            if (gainRef.current) {
                gainRef.current.gain.value = volume;
            }
        } else if (animationRef.current) {
            cancelAnimationFrame(animationRef.current);
        }

        // 组件卸载时清除所有定时器
        return () => {
            if (animationRef.current) cancelAnimationFrame(animationRef.current);
            if (intervalRef.current) clearInterval(intervalRef.current);
        }
    }, [isPlaying, volume, frequency])

    const stopAudio = () => {
        if (audioCtxRef.current) {
            audioCtxRef.current.close();
            audioCtxRef.current = null;
            if (oscillatorRef.current) {
                oscillatorRef.current.stop();
                oscillatorRef.current = null;
            }
            if (intervalRef.current) {
                clearInterval(intervalRef.current);
                intervalRef.current = null;
            }
            if (musicTimerRef.current) {
                clearTimeout(musicTimerRef.current);
                musicTimerRef.current = null;
            }
            setIsPlaying(false);
        }
    }

    return (
        <Container>
            <Canvas ref={canvasRef} />

            <ControlSection>
                <ControlButton
                    isPlaying={isPlaying}
                    onClick={isPlaying ? stopAudio : initAudio}
                >
                    {isPlaying ? "停止" : "开始"}
                </ControlButton>

                <ControlTextContainer>
                    <FrequencyDisplay>{frequency.toFixed(1)} Hz</FrequencyDisplay>
                    <VibrationInfo>
                        {getBandDescription()} · 每秒振动 {frequency.toFixed(1)} 次
                    </VibrationInfo>
                </ControlTextContainer>

                <BandIndicator band={getFrequencyBand()}>
                    {getFrequencyBand()}
                </BandIndicator>
            </ControlSection>

            {/* 常见频率按钮：调用selectFrequency（持续播放） */}
            <FrequencySection>
                <SectionTitle>常见声音频率（1-25000Hz）</SectionTitle>
                <OctaveRow>
                    {baseFrequencies.map(preset => (
                        <FrequencyButton
                            key={preset.value}
                            active={frequency === preset.value}
                            onClick={() => selectFrequency(preset.value)}
                            // 【移除disabled】未启动也可点击
                        >
                            {preset.label}
                        </FrequencyButton>
                    ))}
                </OctaveRow>
            </FrequencySection>

            {/* 音乐频率按钮：调用playMusicNote（0.5秒自动停） */}
            <FrequencySection>
                <SectionTitle>音乐频率（C调）</SectionTitle>

                <OctaveRow>
                    {musicFrequencies.高音.map(note => (
                        <FrequencyButton
                            key={note.value}
                            active={frequency === note.value}
                            onClick={() => playMusicNote(note.value)}
                            // 【移除disabled】未启动也可点击
                        >
                            高音{note.note}
                            {note.value} Hz
                        </FrequencyButton>
                    ))}
                </OctaveRow>

                <OctaveRow>
                    {musicFrequencies.中音.map(note => (
                        <FrequencyButton
                            key={note.value}
                            active={frequency === note.value}
                            onClick={() => playMusicNote(note.value)}
                        >
                            中音{note.note}
                            {note.value} Hz
                        </FrequencyButton>
                    ))}
                </OctaveRow>

                <OctaveRow>
                    {musicFrequencies.低音.map(note => (
                        <FrequencyButton
                            key={note.value}
                            active={frequency === note.value}
                            onClick={() => playMusicNote(note.value)}
                        >
                            低音{note.note}
                            {note.value} Hz
                        </FrequencyButton>
                    ))}
                </OctaveRow>
            </FrequencySection>

            <Label>频率调节（1-25000 Hz）</Label>
            <Slider
                type="range"
                min="1"
                max="25000"
                step="1"
                value={frequency}
                onChange={(e) => setFrequency(parseFloat(e.target.value))}
            />
            <FineTuneContainer>
                <FineTuneBtn
                    onClick={() => fineTuneFrequency(-5)}
                >
                    -5 Hz
                </FineTuneBtn>
                <FineTuneBtn
                    disabled={!isPlaying && !audioCtxRef.current}
                    onClick={() => fineTuneFrequency(5)}
                >
                    +5 Hz
                </FineTuneBtn>
            </FineTuneContainer>

            <Label>音量</Label>
            <Slider
                type="range"
                min="0"
                max="1"
                step="0.01"
                value={volume}
                onChange={(e) => {
                    const newVol = parseFloat(e.target.value)
                    setVolume(newVol)
                    if (gainRef.current) {
                        gainRef.current.gain.value = newVol
                    }
                }}
            />
        </Container>
    )
}
